<template>
	<view>
		<view class="flex">
			<!-- 单图 -->
			<view class="single" :style="uploadStyle" v-if="showSingle">
				<image class="space-item" v-if="type === 'image'" mode="aspectFit" :src="url"></image>
				<view v-else class="space-item flex justify-center items-center">
					<dx-icon :name="type === 'video' ? 'video' : type === 'audio' ? 'audio-file' : 'file-addition-one'" size="40"></dx-icon>
				</view>
				<view class="shade flex items-center justify-center">
					<dx-icon name="preview-open" size="24" color="#ffffff" @click="previewFile"></dx-icon>
					<dx-icon name="switch" size="24" class="ml-10px" color="#ffffff" @click="chooseImage"></dx-icon>
				</view>
			</view>
			<!-- 选择 -->
			<view class="cursor-pointer flex justify-center items-center choose" :style="uploadStyle" @click="chooseImage" v-if="showSingleChoose">
				<view class="text-center child">
					<dx-icon
						:name="type === 'image' ? 'pic' : type === 'video' ? 'video' : type === 'audio' ? 'audio-file' : 'file-addition-one'"
						size="24"
					></dx-icon>
					<view class="text">选择{{ type === 'image' ? '图片' : type === 'video' ? '视频' : type === 'audio' ? '音频' : '文件' }}</view>
				</view>
			</view>
			<!-- 多图 -->
			<view v-if="showMulti">
				<draggable class="multi flex items-center flex-wrap" v-model="url" item-key="index">
					<template #item="{ element, index }">
						<view class="item mr-15px mb-15px" :style="uploadStyle">
							<image v-if="type === 'image'" mode="aspectFit" class="space-item" :src="element"></image>
							<view v-else class="space-item flex justify-center items-center">
								<dx-icon :name="type === 'video' ? 'video' : type === 'audio' ? 'audio-file' : 'file-addition-one'" size="40"></dx-icon>
							</view>
							<view class="shade flex items-center justify-center">
								<dx-icon name="preview-open" size="24" color="#ffffff" @click="previewFile(index)"></dx-icon>
								<dx-icon name="delete" size="20" class="ml-10px" color="#ffffff" @click="deleteImage(index)"></dx-icon>
							</view>
						</view>
					</template>
					<template #footer>
						<view class="mr-15px mb-15px cursor-pointer flex justify-center items-center choose" :style="uploadStyle" @click="chooseImage" v-if="showMultiChoose">
							<view class="text-center child">
								<dx-icon
									:name="type === 'image' ? 'pic' : type === 'video' ? 'video' : type === 'audio' ? 'audio-file' : 'file-addition-one'"
									size="24"
								></dx-icon>
								<view class="text">选择{{ type === 'image' ? '图片' : type === 'video' ? '视频' : type === 'audio' ? '音频' : '文件' }}</view>
							</view>
						</view>
					</template>
				</draggable>
			</view>
		</view>
		<!-- 文件空间 -->
		<dx-image-space v-model="showSpace" :type="props.type" :mask="props.mask" :limit="props.limit" @confirm="confirm"></dx-image-space>
		<!-- 预览的加载 -->
		<el-image-viewer
			v-if="showImageViewer"
			:initial-index="initialIndex"
			:url-list="props.limit === 1 ? [url] : url"
			@close="showImageViewer = false"
		></el-image-viewer>
	</view>
</template>
<script setup lang="ts" name="DxUpload">
import { computed, ref, watch } from 'vue';
import draggable from 'vuedraggable';
import { multiUpload } from '@/uni_modules/dx-admin/api/index';
import useElFormItem from '@/uni_modules/dx-admin/libs/useElFormItem';
const { emitTrigger } = useElFormItem();
const props = withDefaults(
	defineProps<{
		modelValue: any;
		isSpace?: boolean;
		limit?: number;
		mask?: boolean;
		type?: string;
		extension?: string[];
		width?:number;
		height?:number;
	}>(),
	{
		limit: 1,
		isSpace: true,
		mask: true,
		type: 'image', //video, audio, file
		width:105,
		height:105,
	}
);
const uploadStyle = computed(() => {
	return {
		width: props.width+'px',
		height: props.height+'px',
	};
});
const showSpace = ref(false);
const showImageViewer = ref(false);
const url = ref<any>(props.limit === 1 ? null : []);
const initialIndex = ref(0);
// 绑定关系
const $emit = defineEmits(['update:modelValue', 'change']);
watch(
	() => props.modelValue,
	(val) => {
		if (props.limit === 1) {
			url.value = typeof val === 'string' ? val : Array.isArray(val) ? val[0] : '';
		} else {
			url.value = val || [];
		}
	},
	{ immediate: true }
);
// 单图显示
const showSingle = computed(() => {
	return props.limit === 1 && !!url.value;
});
// 多图显示
const showMulti = computed(() => {
	return props.limit > 1 && !!url.value;
});
const showSingleChoose = computed(() => {
	if (props.limit === 1) {
		return !url.value;
	}
	return false;
});
const showMultiChoose = computed(() => {
	if (props.limit > 1) {
		return url.value.length < props.limit;
	}
	return false;
});
// 更新值
function updateValue(val: any[]) {
	$emit('update:modelValue', val);
	$emit('change', val);
	emitTrigger();
}
// 删除图片
function deleteImage(index: any) {
	url.value.splice(index, 1);
	updateValue(url.value);
}
// 选择图片
function chooseImage() {
	if (props.isSpace) {
		showSpace.value = true;
		return;
	}
	console.log(props.limit, 'props.limit');
	const params: any = {
		count: props.limit > 1 ? props.limit - url.value?.length : props.limit,
	};
	if (props.type === 'image') {
		params.type = 'image';
	} else if (props.type === 'video') {
		params.type = 'video';
	} else {
		let extension = props.extension || [];
		if (!extension.length) {
			if (props.type === 'audio') {
				extension = ['.m4a', '.mp4', '.3gp', '.wav', '.wma', '.mp3'];
			} else {
				// 其他文件
				extension = ['.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.zip', '.rar', '.7z', '.apk'];
			}
		}
		params.extension = extension;
	}
	uni.chooseFile({
		...params,
		success: function (res: any) {
			multiUpload(res.tempFiles)
				.then((urls: any) => {
					if (props.limit === 1) {
						updateValue(urls[0]);
					} else {
						let images = [...url.value, ...urls];
						updateValue(images);
					}
				})
				.finally(() => {});
		},
	});
}
function previewFile(index?: number) {
	if (typeof index === 'number') {
		if (props.type === 'image') {
			initialIndex.value = index;
			showImageViewer.value = true;
		} else {
			window.open(url.value[index]);
		}
		return;
	}
	if (props.type === 'image') {
		showImageViewer.value = true;
	} else {
		console.log(url.value, 'url.value');
		window.open(url.value);
	}
}
// 确认
function confirm(val: any[]) {
	if (props.limit === 1) {
		url.value = val[0];
	} else {
		url.value = [...url.value, ...val];
	}
	updateValue(url.value);
	showSpace.value = false;
}
</script>
<style lang="scss" scoped>
// .single,
// .choose,
// .multi .item {
// 	border-radius: 6px;
// 	width: 105px;
// 	height: 105px;
// }
.single,
.multi .item {
	position: relative;
	border: 1px solid #d9d9d9;
	.shade {
		position: absolute;
		left: 0;
		top: 0;
		width: 100%;
		height: 100%;
		background-color: rgba(0, 0, 0, 0.5);
		display: none;
	}
	&:hover {
		.shade {
			display: flex;
		}
	}
	.space-item {
		width: 100%;
		height: 100%;
	}
}
.choose {
	border: 1px dashed #d9d9d9;
	.child {
		line-height: 20px;
		.text {
			font-size: 14px;
			color: #666666;
		}
	}
	&:hover {
		border-color: var(--el-color-primary);
	}
}
</style>
